package com.fr.ticket;

import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.geo.GeoDistance;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.elasticsearch.search.SearchHit;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * @author 付荣
 * @version 创建时间：2019年4月11日 下午1:49:02
 */
public class CtripSimilarity {
//	private static final String dic_file = "E:\\ticket\\dic.txt";
	private static final String product_relation = "E:\\ticket\\product_relation2.txt";

	public static void main(String[] args) throws IOException {
		TransportClient client = ESUtils.getClient();
		SearchRequestBuilder sr = client.prepareSearch("product_20190419");
		sr.setSize(4);
		SearchRequestBuilder builder = client.prepareSearch("product_20190419").setTypes("product_20190419").setSize(1000);
		builder.setScroll(new TimeValue(10000000));
		BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
		QueryBuilder queryBuilder = QueryBuilders.rangeQuery("price").gte(0.1);
		boolQuery.must(queryBuilder);
		boolQuery.must(QueryBuilders.termsQuery("star", "4", "5"));
		builder.setQuery(boolQuery);
		SearchResponse searchResponse = builder.get();
//		FileWriter dicWriter = new FileWriter(dic_file);
		FileWriter productRelationWriter = new FileWriter(product_relation);
		while (true) {
			for (SearchHit hit : searchResponse.getHits().getHits()) {
				Map<String, Object> source = hit.getSource();
				String id = source.get("id").toString();
				String name = source.get("name").toString();
				String vslat = source.get("vslat").toString();
				String vslon = source.get("vslon").toString();
				String cityname = source.get("cityname").toString();
				String price = String.valueOf(source.get("price"));
				String address = String.valueOf(source.get("address"));
				address = address.replaceAll("\r", "").replaceAll("\t", "").replaceAll("\n", "");
				name = name.replaceAll("\r", "").replaceAll("\t", "").replaceAll("\n", "");
				String provinceName = DestStaticData.map.get(cityname);
				String star = String.valueOf(source.get("star"));
				// String price = source.get("price").toString();
				List<String> tokens = LvmamaDataUtil.getAnalyzer(name);
				if (CollectionUtils.isNotEmpty(tokens)) {
					BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
					FunctionScoreQueryBuilder functionScoreQuery = QueryBuilders.functionScoreQuery(boolQueryBuilder);
					boolQueryBuilder.must(QueryBuilders.termQuery("cityName", cityname));
					boolQueryBuilder.must(QueryBuilders.termsQuery("categoryId", "11", "12"));
//					boolean failFirst = true;
					for (int i = 0; i < tokens.size(); i++) {
						String token = tokens.get(i);
						if (token.length() < 2) {
//							if(failFirst){
//								failFirst = false;
//								dicWriter.append("分词结果异常:" + name + ":" + tokens + "\n");
//							}
							boolQueryBuilder.should(QueryBuilders.wildcardQuery("productName", "*" + token + "*").queryName("name_" + i));
							functionScoreQuery.add(QueryBuilders.wildcardQuery("productName", "*" + token + "*"), ScoreFunctionBuilders.weightFactorFunction(3));
						} else {
							boolQueryBuilder.should(QueryBuilders.termQuery("productName", token).queryName("name_" + i));
							functionScoreQuery.add(QueryBuilders.termQuery("productName", token), ScoreFunctionBuilders.weightFactorFunction(6));
						}
					}
					functionScoreQuery.add(QueryBuilders.geoDistanceRangeQuery("location").point(Double.parseDouble(vslat), Double.parseDouble(vslon)).gt(0).lte(1000).geoDistance(GeoDistance.PLANE)
							.queryName("KM_1"), ScoreFunctionBuilders.weightFactorFunction(4));
					functionScoreQuery.add(QueryBuilders.geoDistanceRangeQuery("location").point(Double.parseDouble(vslat), Double.parseDouble(vslon)).gt(1000).lte(5000)
							.geoDistance(GeoDistance.PLANE).queryName("KM_5"), ScoreFunctionBuilders.weightFactorFunction(2));
					if (tokens.size() >= 5) {
						boolQueryBuilder.minimumNumberShouldMatch(3);
					} else if (tokens.size() >= 3) {
						boolQueryBuilder.minimumNumberShouldMatch(2);
					}else {
						boolQueryBuilder.minimumNumberShouldMatch(1);
					}
					sr.setQuery(functionScoreQuery);
					String string = LvmamaDataUtil.getTicketProductOrGoods(sr.toString(), 1);
					JSONObject object = JSON.parseObject(string);
					List<JSONObject> ticketProduct = (List<JSONObject>) ((JSONObject) object.get("hits")).get("hits");
					if (CollectionUtils.isNotEmpty(ticketProduct)) {
						if (ticketProduct.size() > 1) {
							boolean f = true;
							for (JSONObject jo : ticketProduct) {
								JSONObject j = jo.getJSONObject("_source");
								String lvmamaProductName = String.valueOf(j.get("productName"));
								lvmamaProductName = lvmamaProductName.replaceAll("\r", "").replaceAll("\t", "").replaceAll("\n", "");
								String lvmamaAddress = String.valueOf(j.get("address"));
								lvmamaAddress = lvmamaAddress.replaceAll("\r", "").replaceAll("\t", "").replaceAll("\n", "");
								String lvmamaStar = String.valueOf(j.get("star"));
								if (f) {
									productRelationWriter.append(provinceName + "\t" + 2 + "\t" + id + "\t" + name + "\t" + address + "\t" + price + "\t" + star + "\t" +j.get("productId") + "\t" + lvmamaProductName + "\t" + lvmamaAddress + "\t" + j.get("sellPrice") + "\t" + lvmamaStar + "\t其他可能结果:");
									f = false;
								} else {
									productRelationWriter.append("\t" + j.get("productId") + "\t" + lvmamaProductName + "\t" + lvmamaAddress + "\t" + j.get("sellPrice") + "\t" + lvmamaStar + "\t");
								}
							}
							productRelationWriter.append("\n");
						} else {
							JSONObject first = ticketProduct.get(0);
							JSONObject j = first.getJSONObject("_source");
							String lvmamaProductName = String.valueOf(j.get("productName"));
							lvmamaProductName = lvmamaProductName.replaceAll("\r", "").replaceAll("\t", "").replaceAll("\n", "");
							String lvmamaAddress = String.valueOf(j.get("address"));
							lvmamaAddress = lvmamaAddress.replaceAll("\r", "").replaceAll("\t", "").replaceAll("\n", "");
							String lvmamaStar = String.valueOf(j.get("star"));
							productRelationWriter.append(provinceName + "\t" + 1 + "\t" + id + "\t" +name + "\t" + address + "\t" + price + "\t" + star  + "\t" + j.get("productId") + "\t" + lvmamaProductName + "\t" + lvmamaAddress + "\t" + j.get("sellPrice") + "\t" + lvmamaStar + "\n");
						}
					} else {
						productRelationWriter.append(provinceName + "\t" + 3 + "\t" + id + "\t" + name + "\t" + address + "\t" + price + "\t" + star + "\t" + "无匹配结果" +"\n");
					}

				} else {
//					dicWriter.append("分词无结果:" + name + ":" + tokens + "\n");
				}
			}
			searchResponse = client.prepareSearchScroll(searchResponse.getScrollId()).setScroll(new TimeValue(10000000)).get();
			if (searchResponse.getHits().getHits().length == 0) {
				break;
			}
		}
//		dicWriter.close();
		productRelationWriter.close();
	}

}
